package framework.elements;

import java.util.Calendar;
import java.util.Locale;

import org.openqa.selenium.By;
import org.testng.Assert;

/**
 * This element is developed for custom calendars.
 * Date selection is based on the java.util.Calendar instance.
 * Date could be selected only from a future.
 */
public class DateCalendar extends BaseElement {

    private Label months = new Label(
            By.cssSelector("div[class~='calendar'] span[class~='month']"),
            "Current month");
    private Label year = new Label(
            By.cssSelector("div[class~='calendar'] span[class~='year']"),
            "Current year");
    private Button nextMonth = new Button(By.linkText(">"), "Next Month");
    private String datexPath = "//td[contains(@class,'valid')][text()='%1$s']";

    public DateCalendar(final By tagName, final String name) {
        super(tagName, name);
    }

    @Override
    protected final String getElementType() {
        return "Calendar";
    }

    /**
     * Perfomance restriction: year selection is restricted by current year+2.
     * @param date
     *          Date to be set
     */
    public final void selectDate(final Calendar date) {
        // Open calendar
        this.click();
        // Year selection
        int yearNeed = date.get(Calendar.YEAR);
        info(String.format("Selecting year %1$s", yearNeed));
        Assert.assertTrue(
                yearNeed - Integer.parseInt(year.getText()) < 2,
                "Selected year is too big");
        while (yearNeed > Integer.parseInt(year.getText())) {
            nextMonth.click();
        }
        // Month selection
        Assert.assertEquals(
                Integer.parseInt(year.getText()), yearNeed,
                "Year is wrong");
        info(String.format(Locale.US, "Selecting month %1$tB", date));
        while (!String.format(Locale.US, "%1$tB", date).trim()
                .equalsIgnoreCase(months.getText().trim())) {
            nextMonth.click();
            Assert.assertEquals(
                    Integer.parseInt(year.getText()), yearNeed,
                    "Year is wrong");
        }
        // Date selection
        int day = date.get(Calendar.DAY_OF_MONTH);
        info(String.format("Selecting day %1$s", day));
        Button dayValid = new Button(By.xpath(String
                .format(datexPath, day + "")), day + "");
        dayValid.click();
    }
}
